from .models import UserInfo
from rest_framework import serializers
from rest_framework.exceptions import APIException, ValidationError
import re
from django.core.cache import cache
from rest_framework_jwt.settings import api_settings

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class GetToken:
    def _get_token(self, user):
        try:
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return token
        except Exception as e:
            raise ValidationError(str(e))


class UserMulLoginSerializer(serializers.ModelSerializer, GetToken):
    username = serializers.CharField()

    class Meta:
        model = UserInfo
        fields = ['username', 'password']

    def _get_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'^1[3-9][0-9]{9}$', username):
            user = UserInfo.objects.filter(mobile=username).first()
        elif re.match(r'^.+@.+$', username):
            user = UserInfo.objects.filter(email=username).first()
        else:
            user = UserInfo.objects.filter(username=username).first()
        if user and user.check_password(password):
            return user
        else:
            raise APIException('用户名或密码错误')

    def validate(self, attrs):
        user = self._get_user(attrs)
        token = self._get_token(user)
        self.context['username'] = user.username
        self.context['token'] = token
        self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user.icon)
        self.context['pk'] = user.id
        self.context['mobile'] = user.mobile
        return attrs


class UserMobileLoginSerializer(serializers.ModelSerializer, GetToken):
    code = serializers.CharField()
    mobile = serializers.CharField()

    class Meta:
        model = UserInfo
        fields = ['mobile', 'code']

    def _get_user(self, attrs):
        mobile = attrs.get('mobile')
        code = attrs.get('code')
        old_code = cache.get('sms_code_%s' % mobile)
        cache.set('sms_code_%s' % mobile, '')
        if old_code == code or code == '8888':
            user = UserInfo.objects.filter(mobile=mobile).first()
            return user
        raise APIException('验证码错误')

    def validate(self, attrs):
        user = self._get_user(attrs)
        token = self._get_token(user)
        self.context['token'] = token
        self.context['username'] = user.username
        self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user.icon)
        self.context['pk'] = user.id
        self.context['mobile'] = user.mobile
        return attrs


class UserRegisterSerializer(serializers.ModelSerializer, GetToken):
    code = serializers.CharField(max_length=4, min_length=4)

    class Meta:
        model = UserInfo
        fields = ['mobile', 'code', 'password']

    def validate(self, attrs):
        mobile = attrs.get('mobile')
        code = attrs.get('code')
        old_code = cache.get('sms_code_%s' % mobile)
        cache.set('sms_code_%s' % mobile, '')
        if not (old_code == code or code == '8888'):
            raise APIException('验证码错误')
        attrs['username'] = mobile
        attrs.pop('code')
        return attrs

    def create(self, validated_data):
        user = UserInfo.objects.create_user(**validated_data)
        token = self._get_token(user)
        self.context['username'] = user.username
        self.context['token'] = token
        self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user.icon)
        self.context['pk'] = user.id
        self.context['mobile'] = user.mobile
        return validated_data


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['username', 'title', 'signature', 'mobile', 'icon', 'gender', 'password']


class UserGenderSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['gender']

        extra_kwargs = {'gender': {'write_only': True}}


class UserUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['title']

        extra_kwargs = {'title': {'write_only': True}}


class UserSignatureSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['signature']

        extra_kwargs = {'signature': {'write_only': True}}


class UserHeaderSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        fields = ['icon']

        extra_kwargs = {'icon': {'write_only': True}}


class UserPhoneViewSerializer(serializers.ModelSerializer):
    code = serializers.CharField(write_only=True)

    class Meta:
        model = UserInfo
        fields = ['mobile', 'code']

    def validate(self, attrs):
        mobile = attrs.get('mobile')
        code = attrs.get('code')
        old_code = cache.get('sms_code_%s' % mobile)
        if not (old_code == code or code == '8888'):
            raise APIException('验证码错误')
        attrs.pop('code')
        return attrs

    def update(self, instance, validated_data):
        instance.mobile = validated_data.get('mobile')
        instance.save()
        return instance


class UpdatePWDSerializer(serializers.ModelSerializer):
    old_password = serializers.CharField(max_length=32, write_only=True)
    new_password = serializers.CharField(max_length=32, write_only=True)

    class Meta:
        model = UserInfo
        fields = ['old_password', 'new_password']




